package com.han.spider.cloudmeeting;

import com.han.util.Encryptors;
import com.han.util.UnZipper;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

/**
 * @Author: Hanjiafeng
 * @Date: 2020/6/28
 * @Desc:
 */
@Slf4j
public class WebSiteLogin {
    private final HttpClient httpClient;
    private final String username;
    private final String password;
    private final HttpRequest.Builder requestBuilder;

    public WebSiteLogin(String username, String password) {
        this.username = username;
        this.password = password;

        HttpClient.Builder clientBuilder = HttpClient.newBuilder();

        httpClient = clientBuilder
                .build();

        requestBuilder = HttpRequest.newBuilder()
                .timeout(Duration.ofMinutes(1));
    }

    public String login() throws IOException, InterruptedException {

        String methodBody = String.format("user=%s&time=%d&zone=8&lang=cn&version=1.1.0&platform=web", username, System.currentTimeMillis());
        String body = childLogin(methodBody);
        JSONObject parameterJson = new JSONObject(body);
        String nonce = parameterJson.getString("nonce");
        String realm = parameterJson.getString("realm");

        if (realm.isBlank() || nonce.isBlank()) {
            throw new IllegalArgumentException("realm/nonce为空");
        }

        //密码加密
        String encryptedPassword = encrypt(realm, nonce);

        methodBody = String.format("user=%s&time=%d&zone=8&lang=cn&version=1.1.0&platform=web&password=%s", username, System.currentTimeMillis(), encryptedPassword);
        body = childLogin(methodBody);
        JSONObject remoteJson = new JSONObject(body);
        JSONArray tempArray = remoteJson.getJSONArray("ws");
        String wsUri = tempArray.getString(0);

        if (wsUri.isBlank()) {
            throw new IllegalArgumentException("ws为空");
        }

        return wsUri;
    }

    private String childLogin(String methodBody) throws IOException, InterruptedException {
        String url = "http://47.97.118.206:7088/user/login?";
        HttpRequest httpRequest = requestBuilder
                .setHeader("Accept", "*/*")
                .setHeader("Accept-Encoding", "gzip, deflate")
                .setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .setHeader("Access-Control-Request-Headers", "content-type")
                .setHeader("Access-Control-Request-Method", "POST")
                .setHeader("Origin", "http://www.ctcloudmeeting.com")
                .setHeader("Referer", "http://www.ctcloudmeeting.com/manage/")
                .setHeader("Sec-Fetch-Mode", "cors")
                .setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36 Edg/83.0.478.54")
                .uri(URI.create(url + methodBody))
                .method("OPTIONS", HttpRequest.BodyPublishers.ofString(methodBody))
                .build();
        httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofByteArray());

        httpRequest = requestBuilder
                .setHeader("Accept", "*/*")
                .setHeader("Accept-Encoding", "gzip, deflate")
                .setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
                .setHeader("Content-Type", "application/json")
                .setHeader("DNT", "1")
                .setHeader("Origin", "http://www.ctcloudmeeting.com")
                .setHeader("Referer", "http://www.ctcloudmeeting.com/manage/")
                .setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36 Edg/83.0.478.54")
                .uri(URI.create(url + methodBody))
                .POST(HttpRequest.BodyPublishers.ofString(methodBody))
                .build();
        HttpResponse<byte[]> byteResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofByteArray());
        return new String(UnZipper.unGzipByBytes(byteResponse.body()), StandardCharsets.UTF_8);
    }

    private String encrypt(String realm, String nonce) {
        String firstPa = Encryptors.md5(password);
        String readyPa = String.format("%s:%s:%s:%s", username, realm, firstPa, nonce);
        return Encryptors.md5(readyPa);
    }
}
